<?php

namespace AbstractFactory;


class Client
{
    public static function main()
    {
        // create factory
        $factory = new FactoryA();

        // create product and service
        $product = $factory->createProduct();
        $product->display();
        $service = $factory->createService();
        $service->serve();

        // create an other factory
        $factory = new FactoryB();

        // create product and service
        $product = $factory->createProduct();
        $product->display();
        $service = $factory->createService();
        $service->serve();
    }
}


/**
 * 由具体工厂决定如何创建产品
 * Interface Factory
 * @package AbstractFactory
 */
interface Factory
{
    public function createProduct(): Product;
    public function createService(): Service;
}

/**
 * 提供A类产品和服务
 * Class FactoryA
 * @package AbstractFactory
 */
class FactoryA implements Factory
{

    public function createProduct(): Product
    {
        return new ProductA();
    }

    public function createService(): Service
    {
        return new ServiceA();
    }
}

/**
 * 提供B类产品和服务
 * Class FactoryB
 * @package AbstractFactory
 */
class FactoryB implements Factory
{

    public function createProduct(): Product
    {
        return new ProductB();
    }

    public function createService(): Service
    {
        return new ServiceB();
    }
}


interface Product
{
    public function display(): void;
}

class ProductA implements Product
{

    public function display(): void
    {
        echo 'product A description.', PHP_EOL;
    }
}

class ProductB implements Product
{

    public function display(): void
    {
        echo 'product B description.', PHP_EOL;
    }
}

interface Service
{
    public function serve(): void;
}

class ServiceA implements Service
{

    public function serve(): void
    {
        echo 'service A is serving.', PHP_EOL;
    }
}

class ServiceB implements Service
{

    public function serve(): void
    {
        echo 'service B is serving.', PHP_EOL;
    }
}


Client::main();
